#include <string.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

class String{
public:
    String():_pstr(new char[1]())   {   }
    String(const char *pstr)
        :_pstr(new char[strlen(pstr)+1])
    {
        strcpy(_pstr,pstr);
    }

    String(const String &rhs)
        :_pstr(new char[strlen(rhs._pstr)+1]){
            strcpy(_pstr,rhs._pstr);
        }
    
    int size()const{     return strlen(_pstr);   }
    char * data(){  return _pstr;  }
    char * c_str(){  return _pstr;  }

    String & append(const String &rhs){
        int len=strlen(rhs._pstr)+this->size()+1;
        char * temp=new char[len]();
        strcpy(temp,_pstr);
        strcat(temp,rhs._pstr);
        delete [] _pstr;
        _pstr=temp;
        return *this;
    }

    String &append(const char * pstr){
        String temp(pstr);
        this->append(temp);
        return *this;
    }

    String &operator=(const String &rhs){
        if(this!=&rhs){
        delete[]_pstr;
        _pstr=new char[strlen(rhs._pstr)+1];
        strcpy(_pstr,rhs._pstr);
        }
        return *this;    
        
    }
    
    String &operator=( char * rhs){
        _pstr=rhs;
        return *this;
    }
    
    bool operator>(String &rhs){    return strcmp(this->_pstr,rhs._pstr)>0;     }
    bool operator<(String &rhs){    return strcmp(this->_pstr,rhs._pstr)<0;     }
    bool operator>=(String &rhs){    return strcmp(this->_pstr,rhs._pstr)>=0;     }
    bool operator<=(String &rhs){    return strcmp(this->_pstr,rhs._pstr)<=0;     }
    bool operator==(String &rhs){    return strcmp(this->_pstr,rhs._pstr)==0;     }
    bool operator!=(String &rhs){    return strcmp(this->_pstr,rhs._pstr)!=0;     }

    friend  ostream& operator<<(ostream& os,const String &rhs);
    friend  istream& operator>>(istream& is,String &rhs);
    
    String & operator+=(const String &rhs){
        if(rhs.size()>0)    this->append(rhs._pstr);
        return *this;
    }
    
    String & operator+=(const char *rhs){
        if(strlen(rhs)>0)   this->append(rhs);
        return *this;
    }


    ~String(){
        if(_pstr){
            delete []_pstr;
            _pstr=nullptr;
        }
    }

private:
    char * _pstr;

};

String  operator+(const String &lhs,const String &rhs){
    String temp(lhs);
    temp.append(rhs);
    return temp; 
}

String operator+(const String &lhs,const char * pstr){
    String temp(lhs);
    temp.append(pstr);
    return temp;
}

String operator+(const char * lhs,const String rhs){
    String temp(lhs);
    temp.append(rhs);
    return temp;
}


ostream& operator<<(ostream& os,const String &rhs){
    os<<rhs._pstr;
    return os;
}

istream& operator>>(istream& is,String &rhs){
    vector<char> vec;
    char ch;
    while((ch=is.get())!='\n'){
        vec.emplace_back(ch);
    }
    delete [] rhs._pstr;
    rhs._pstr = new char[vec.size()+1]();
    for(unsigned long i=0;i<vec.size();i++){
        rhs._pstr[i]=vec[i];
    }
    return is;
}
void test(){
    String s1;
    cout<<"--- s1: "<<s1<<" ---"<<endl;

    String s2("i'm s2");
    cout<<"--- s2: "<<s2<<" ---"<<endl;
    
    cout<<"--- s2+=s1: "<<(s2+=s1)<<" ---"<<endl;

    cout<<"--- s1>s2: "<<(s1>s2)<<" ---"<<endl;

    String s3=s2;
    cout<<"--- s3: "<<s3<<" ---"<<endl;
    cout<<"--- s3==s2: "<<(s3==s2)<<" ---"<<endl;
    cout<<"--- s3!=s2: "<<(s3!=s2)<<" ---"<<endl;

    String s4;
    s4=s3;
    cout<<"--- s4: "<<s4<<" ---"<<endl;

    String s5="hello";
    s5.append("world");
    cout<<"--- s5: "<<s5<<" ---"<<endl;
    
    String s6="Kill";
    cout<<"--- before s6: "<<s6<<" ---"<<endl;

    String s7("Hi ");
    String s8="Python";
    cout<<"--- s7: "<<s7<<" s8: "<<s8<<" ---"<<endl;

    s7+=s8;
    cout<<"--- s7+=s8: "<<s7<<" ---"<<endl;
    s7+=" C++";
    cout<<"--- s7+=\"C++\": "<<s7<<" ---"<<endl;
    //cin>>s6;
    //cout<<"--- after s6: "<<s6<<" ---"<<endl;
    //

    String s9=s7+"LOOKKK";
    cout<<"--- s9= "<<s9<<" ---"<<endl;

    }

int main()
{
 test();
 return 0;
}

